/*************************************************************************
** Name		: xUtils.h
** Desc		: 一些比较杂的工具函数
** Author	: xktesla
*************************************************************************/

#ifndef _B96098F5_26FA_4B6C_8F52_6E9C7FB7C31E
#define _B96098F5_26FA_4B6C_8F52_6E9C7FB7C31E

#include "depends/incfile.h"

namespace x2lib
{
	namespace xUtils
	{
		/**
		* @brief        巧用union实现类型转换，如函数指针转换
		* @param[in]    src
		* @return       
		* @author       xktesla
		*/
		template<typename dst_type, typename src_type>
		dst_type union_cast(src_type src)
		{
			union
			{
				src_type s;
				dst_type d;
			}u;
			u.s = src;
			return u.d;
		}

		/**
		* @brief        获取函数地址。很久未用，谨慎使用
		* @param[in]    f 任意函数名
		* @return
		* @author       xktesla
		*/
		template<class F>
		void* GetFuncAddr(F f)
		{
			//void(Listener::*pfunc)(void) = (void(Listener::*)(void))&Listener::OnIsLogined;
			//return *(int*)&pfunc;
			return *(int*)(&f);
		}

		// 摘自网络
#define asm_cast(var,addr)					\
			{								\
				__asm{						\
					mov var, offset addr	\
				}							\
			}

		// 支持将带捕获的lambda转函数指针
		template <class F, class L>
		F lambda2func(L lambda)
		{
			static auto lambdabak = lambda;

			return F(); //static_cast<F>([]() { lambdabak(); });
		}

		// 用法：HasReturnType<decltype(functionWithoutReturnValue)>::value
		template <typename T>
		struct HasReturnType 
		{
			// 使用SFINAE技术，尝试匹配函数的返回类型
			template <typename U>
			static std::true_type test(decltype(std::declval<U>()())*);

			// 当无法匹配到返回类型时，使用这个重载
			template <typename U>
			static std::false_type test(...);

			// 定义一个成员常量来存储测试结果
			static const bool value = decltype(test<T>(nullptr))::value;
		};
	}
}

#endif


